"use client"
import {
    ColumnDef,
    flexRender,
    getCoreRowModel,
    getFilteredRowModel,
    getPaginationRowModel,
    getSortedRowModel,
    useReactTable
} from "@tanstack/react-table"
import {Checkbox} from "@/components/ui/checkbox";
import {Button} from "@/components/ui/button";
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
import {DataTablePagination} from "@/components/page/data-table-pagination";
import {useCallback, useEffect, useState} from "react";
import {Input} from "@/components/ui/input";
import {Label} from "@/components/ui/label";
import {Card} from "@/components/ui/card";
import {sexInfo, SexInfoKey, statusInfo, StatusInfoKey, UserInfo} from "@/lib/db/types";
import {formatDate} from "date-fns";
import {useIsMobile} from "@/hooks/use-mobile";
import {cn, getSearchParams} from "@/lib/utils";
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from "@/components/ui/select";
import {Edit, Ellipsis, RotateCcw, Search, Trash2, UserRoundPlus} from "lucide-react";
import {Calendar} from "@/components/ui/calendar";
import {Popover, PopoverContent, PopoverTrigger} from "@/components/ui/popover";
import {Controller, FormProvider, useForm} from "react-hook-form";
import {UserListSerachFormSchema} from "@/lib/zod/schema";
import {z} from "zod";
import {zodResolver} from "@hookform/resolvers/zod";
import {toast} from "sonner";
import {useRouter} from "next/navigation";
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
    AlertDialogTrigger
} from "@/components/ui/alert-dialog";


const initValue = {
    email:"",
    sex:"all",
    status:"all",
    username:"",
    createdAt: {
        from:undefined,
        to:undefined
    },
};


export default function Page() {

    //是否手机
    const isMobile = useIsMobile();
    //初始化的分页信息
    const initPagination = {pageIndex: 0,pageSize: 10,};
    //数据信息
    const [dataInfo, setDataInfo] = useState<{ data: Array<UserInfo>, rowCount: 0 }>({data: [], rowCount: 0})
    //分页信息
    const [pagination, setPagination] = useState(initPagination);
    //是否显示搜索条件
    const [showCondition, setShowCondition] = useState<boolean>(false);
    //日历选择框
    const {register, handleSubmit,  reset, control,...form} = useForm({
        resolver:zodResolver(UserListSerachFormSchema),
        defaultValues:initValue
    });
    const router = useRouter();

    const search = useCallback((data: z.infer<typeof UserListSerachFormSchema> = {sex: "all", status: "all",createdAt: {from: undefined}}) => {

        const createdAtStr = JSON.stringify(data.createdAt, (key, value) => {
            if (key && (key === 'to' || key === 'from') && value instanceof Date) {
                return formatDate(value, "yyyy-MM-dd")
            }
            return value;
        });

        //参数
        const searchParams = getSearchParams(Object.assign({}, data, pagination, {createdAt: JSON.parse(createdAtStr)}));
        //查询
        fetch(`/api/users?${searchParams.toString()}`).then(async (rs) => {
            const {data} = await rs.json();
            setDataInfo(data)
        });
    }, [pagination])

    const  dropUser = useCallback((userId:number)=>{

        fetch(`/api/user/${userId}`,{
            method:"DELETE",
        }).then(async (rs)=>{
            const {code} = await rs.json();
            if (code === 200) {
                search();
                return;
            }
            toast("删除失败",{
                description:"删除用户失败",
                action:{
                  label:"取消",
                  onClick:()=>{
                    console.log("取消了")
                  }
                },
                duration:1000
            })
        }).catch(()=>{
            toast("删除失败",{
                description:"删除用户失败",
                action:{
                    label:"取消",
                    onClick:()=>{
                        console.log("取消了")
                    }
                },
                duration:1000
            })
        })
    },[search])

    const  editUser = useCallback((user:UserInfo)=>{
        router.push(`/home/user/${user.userId}`);
    },[router])



    const columns: ColumnDef<UserInfo>[] = [
        {
            accessorKey: "userId",
            header: ({ table }) => {
                return <span className={"flex items-center gap-2"}>
                    <Checkbox
                        id={"select_all_id"}
                        checked={
                            table.getIsAllPageRowsSelected() ||
                            (table.getIsSomePageRowsSelected() && "indeterminate")
                        }
                        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
                        aria-label="全选"
                    />
                    <label htmlFor={"select_all_id"} className={"hidden lg:block"}>全选</label>
                </span>
            },
            cell: ({ row }) => {
                return  <Checkbox
                    checked={row.getIsSelected()}
                    onCheckedChange={(value) => row.toggleSelected(!!value)}
                    aria-label="选择行" className={"flex items-center"}
                />
            },
            enableSorting: false,
            enableHiding: false,
        },
        {
            accessorKey: "username",
            header: "用户名",
            cell:({ row }) => {
                return <div className={"overflow-hidden overflow-ellipsis whitespace-nowrap w-20 lg:w-fit"}>{row.original.username}</div>;
            }
        },
        {
            accessorKey: "email",
            header: "邮箱",
            cell: ({ row }) => {
                return <div className={"overflow-hidden overflow-ellipsis whitespace-nowrap w-20 lg:w-fit"}>{row.original.email}</div>;
            },
        },
        {
            accessorKey: "sex",
            header: () => <div className="text-left  overflow-ellipsis overflow-hidden whitespace-nowrap w-8 lg:w-fit" >性别</div>,
            cell: ({ row }) => {
                const sex = row.getValue<SexInfoKey>("sex");
                return sexInfo[sex]??"其他";
            },
        },
        {
            accessorKey: "status",
            header: () => <div className="text-left  overflow-ellipsis overflow-hidden whitespace-nowrap w-8 lg:w-fit" >状态信息</div>,
            cell: ({ row }) => {
                const status = row.getValue("status") as StatusInfoKey;

                return <div className="text-left font-medium">{statusInfo[status]??"未知"}</div>
            },
        },
        {
            accessorKey: "createdAt",
            header: () => <div className="text-left">创建时间</div>,
            cell: ({ row }) => {
                const createdAt = row.getValue<string>("createdAt");

                return <div className="text-left font-medium overflow-ellipsis overflow-hidden whitespace-nowrap w-20 lg:w-fit"  title={createdAt}>{createdAt}</div>
            },
        },
        {
            accessorKey: "updatedAt",
            header: () => <div className="text-left">修改时间</div>,
            cell: ({ row }) => {
                const updatedAt = row.getValue<string>("updatedAt");

                return <div className="text-left font-medium overflow-ellipsis overflow-hidden whitespace-nowrap w-20 lg:w-fit" title={updatedAt}>{updatedAt}</div>
            },
        },
        {
            accessorKey: "edit",
            header: () => <div className="text-left">编辑</div>,
            cell: ({row}) => {

                const userId = row.getValue<number>("userId");

                return <div className="flex justify-start gap-3">
                    <Button variant={"outline"} size={"sm"} onClick={()=>{
                        editUser(row.original);
                    }}>编辑</Button>
                    <Button variant={"outline"} size={"sm"} onClick={()=>{
                        dropUser(userId);
                    }}>删除</Button>
                </div>
            },
        },
    ]
    //表格信息
    const table = useReactTable({
        data:dataInfo.data,
        columns,
        rowCount: dataInfo.rowCount,
        getCoreRowModel: getCoreRowModel(),
        getPaginationRowModel: getPaginationRowModel(),
        getSortedRowModel: getSortedRowModel(),
        getFilteredRowModel: getFilteredRowModel(),
        onPaginationChange: setPagination,
        manualPagination: true,
        debugTable: false,
        state: {
            pagination,
        },
    })



    useEffect(() => {
        search()
    }, [search]);

    const  batchDrop =()=>{
        const selectAll = table.getSelectedRowModel();
        if(!selectAll || !selectAll.rows || selectAll.rows.length ===0){
            return;
        }
        const userIds = selectAll.rows.map(it=>it.original.userId);

        fetch("/api/users",{
            method:"DELETE",
            body:JSON.stringify(userIds)
        })
        .then((rs)=>rs.json())
        .then(({code,msg})=>{
            if (code === 200) {
                search();
                return;
            }
            toast("删除失败",{
                description:`${msg}`,
                action:{
                    label:"取消",
                    onClick:()=>{
                        console.log("取消了")
                    }
                },
                duration:1000
            })
        }).catch(()=>{
            toast("删除失败",{
                description:`网络异常`,
                action:{
                    label:"取消",
                    onClick:()=>{
                        console.log("取消了")
                    }
                },
                duration:1000
            })
        })
    }

    return (
        <>
            <div className={"p-4"}>
                <FormProvider {...form} register={register} control={control} handleSubmit={handleSubmit} reset={reset} >
                    <form onSubmit={handleSubmit(search)}>
                        <div className={"flex  flex-wrap md:grid  md:grid-cols-2 lg:grid-cols-3  rounded h-fit my-2 gap-3"}>
                            <div className={"flex items-center w-60"}>
                                <Label htmlFor={"username"} className={"flex-shrink-0 w-20"}>用户名：</Label>
                                <Input id={"username"} {...register("username")}/>
                            </div>
                            <div
                                className={cn("items-center w-60 hidden", {"flex": !isMobile || (showCondition && isMobile)})}>
                                <Label className={"flex-shrink-0 w-20"}>性别：</Label>
                                <Controller render={({field,}) => {
                                    return (<Select value={field.value} onValueChange={field.onChange}>
                                        <SelectTrigger>
                                            <SelectValue placeholder="性别"/>
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value="all">全部</SelectItem>
                                            <SelectItem value="male">男</SelectItem>
                                            <SelectItem value="female">女</SelectItem>
                                        </SelectContent>
                                    </Select>);
                                }} name={"sex"} control={control}/>
                            </div>
                            <div
                                className={cn("items-center w-60 hidden", {"flex": !isMobile || (showCondition && isMobile)})}>
                                <Label htmlFor={"email"} className={"flex-shrink-0 w-20"}>邮箱：</Label>
                                <Input id={"email"} {...register("email")}/>
                            </div>
                            <div className={"flex items-center w-60"}>
                                <Label className={"flex-shrink-0 w-20"}>状态：</Label>
                                <Controller render={({field,}) => {
                                    return (<Select value={field.value} onValueChange={field.onChange}>
                                        <SelectTrigger>
                                            <SelectValue placeholder="状态"/>
                                        </SelectTrigger>
                                        <SelectContent>
                                            <SelectItem value="all">全部</SelectItem>
                                            <SelectItem value="active">激活</SelectItem>
                                            <SelectItem value="freeze">冻结</SelectItem>
                                            <SelectItem value="banned">封禁</SelectItem>
                                        </SelectContent>
                                    </Select>);
                                }} name={"status"} control={control}/>
                            </div>
                            <div
                                className={cn("items-center w-60 hidden", {"flex": !isMobile})}>
                                <Label className={"flex-shrink-0 w-20"}>创建时间：</Label>
                                <Controller render={({field,}) => {
                                    const value = field.value;
                                    return (
                                        <Popover>
                                            <PopoverTrigger asChild>
                                                <Button
                                                    variant={"outline"}
                                                    className={cn(
                                                        "w-full justify-start text-xs font-normal overflow-hidden overflow-ellipsis whitespace-nowrap",
                                                        !value && "text-muted-foreground"
                                                    )}
                                                >
                                                    {/* <CalendarIcon/>*/}
                                                    {
                                                        value && value.from ? formatDate(value.from, "yyyy-MM-dd") :
                                                            <span>开始日期</span>
                                                    }
                                                    至
                                                    {
                                                        value && value.to ? formatDate(value.to, "yyyy-MM-dd") :
                                                            <span>结束日期</span>
                                                    }
                                                </Button>
                                            </PopoverTrigger>
                                            <PopoverContent className="w-auto p-0">
                                                <Calendar
                                                    mode={"range"}
                                                    selected={{from: value.from, to: value.to}}
                                                    onSelect={field.onChange}
                                                    initialFocus
                                                />
                                            </PopoverContent>
                                        </Popover>
                                    )
                                }} name={"createdAt"} control={control}/>
                            </div>
                            <div className={"flex items-center justify-start w-60 gap-3"}>
                                <Button variant={"outline"} size={"sm"} type={"submit"}>
                                    <Search/>
                                    <span className={"hidden md:block"}>搜索</span>
                                </Button>

                                <Button variant={"outline"} size={"sm"} type={"button"} onClick={() => {
                                    reset();
                                    search();
                                }}>
                                    <RotateCcw/>
                                    <span className={"hidden md:block"}>重置</span>
                                </Button>

                                <Button variant={"outline"} size={"sm"} type={"button"} onClick={() => {
                                    router.push("/home/user/add");
                                }}>
                                    <UserRoundPlus/>
                                    <span className={"hidden md:block"}>新建</span>
                                </Button>
                            </div>
                            <div className={"items-center justify-start w-60 gap-3 flex"}>
                                <Button variant={"outline"} size={"sm"} type={"button"}  className={cn("flex items-center", {"hidden": isMobile})} onClick={batchDrop}>
                                    <Trash2 />
                                    <span>批量删除</span>
                                </Button>
                                <Button variant={"outline"} type={"button"}
                                        className={cn("hidden", {"flex": isMobile})}
                                        onClick={() => setShowCondition(!showCondition)}>
                                    <Ellipsis/>
                                </Button>
                            </div>
                        </div>
                    </form>
                </FormProvider>

                <div className={"rounded-md md:border"}>
                    <Table className={"hidden md:table"}>
                        <TableHeader>
                            {table.getHeaderGroups().map((headerGroup) => (
                                <TableRow key={headerGroup.id}>
                                    {headerGroup.headers.map((header) => {
                                        return (
                                            <TableHead key={header.id}>
                                                {header.isPlaceholder
                                                    ? null
                                                    : flexRender(
                                                        header.column.columnDef.header,
                                                        header.getContext()
                                                    )}
                                            </TableHead>
                                        )
                                    })}
                                </TableRow>
                            ))}
                        </TableHeader>
                        <TableBody>
                            {table.getRowModel().rows?.length ? (
                                table.getRowModel().rows.map((row) => (
                                    <TableRow
                                        key={row.id}
                                        data-state={row.getIsSelected() && "selected"}
                                    >
                                        {row.getVisibleCells().map((cell) => (
                                            <TableCell key={cell.id}>
                                                {flexRender(cell.column.columnDef.cell, cell.getContext())}
                                            </TableCell>
                                        ))}
                                    </TableRow>
                                ))
                            ) : (
                                <TableRow>
                                    <TableCell colSpan={columns.length} className="h-24 text-center">
                                        无数据
                                    </TableCell>
                                </TableRow>
                            )}
                        </TableBody>
                    </Table>
                    <div className={"flex flex-col gap-3 md:hidden"}>
                        {
                            dataInfo.data.map((it, index) => {
                                return <UserInfoCard userInfo={it} key={index} dropUser={dropUser} editUser={editUser}/>
                            })
                        }
                    </div>
                    {/*分页*/}
                    <DataTablePagination table={table}/>
                </div>

            </div>
        </>
    );
}

/**
 * 用户信息卡片
 * @param it
 * @param dropUser  删除用户函数
 * @param editUser  编辑用户函数
 * @constructor
 */
function UserInfoCard({userInfo: it, dropUser, editUser}: {
    userInfo: UserInfo,
    dropUser?: (userId: number) => void,
    editUser?: (user: UserInfo) => void
}) {

    return <Card  className={"p-2 flex flex-col gap-2 relative"}>
        <div className={"flex  gap-2 items-center absolute right-1 top-1 h-4"}>
            <Edit className={"cursor-pointer"}  onClick={()=>{
                if (editUser != undefined) {
                    editUser(it);
                }
            }}/>
            <AlertDialog>
                <AlertDialogTrigger asChild>
                    <Trash2 className={"cursor-pointer"}/>
                </AlertDialogTrigger>
                <AlertDialogContent className={"rounded w-60 sm:w-full "}>
                    <AlertDialogHeader>
                        <AlertDialogTitle className={"text-left"}>删除用户{it.username}？</AlertDialogTitle>
                        <AlertDialogDescription className={"text-left indent-4"}>
                            点击删除将永久删除用户信息
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel>取消</AlertDialogCancel>
                        <AlertDialogAction onClick={()=>{
                            if (dropUser != undefined) {
                                dropUser(it.userId)
                            }
                        }}>删除</AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
        <div className={"flex items-center w-full mt-4"}>
            <Label className={"flex-shrink-0 w-20"}>用户名：</Label>
            <span
                className={"cursor-text overflow-hidden overflow-ellipsis  whitespace-nowrap "}
                title={it.username}>
                                            {it.username}
                                        </span>
        </div>
        <div className={"flex items-center w-full"}>
            <Label className={"flex-shrink-0 w-20"}>性别：</Label>
            <span className={"cursor-text"}>
                                            {sexInfo[it.sex as SexInfoKey] ?? "其他"}
                                        </span>
        </div>
        <div className={"flex items-center w-full"}>
            <Label className={"flex-shrink-0 w-20"}>邮箱：</Label>
            <span
                className={"cursor-text overflow-hidden overflow-ellipsis whitespace-nowrap "}
                title={it.email}>
                                            {it.email}
                                        </span>
        </div>
        <div className={"flex items-center w-full"}>
            <Label className={"flex-shrink-0 w-20"}>状态信息：</Label>
            <span
                className={"cursor-text overflow-hidden overflow-ellipsis  whitespace-nowrap "}
                title={statusInfo[it.status as StatusInfoKey] ?? "未知"}>
                                            {statusInfo[it.status as StatusInfoKey] ?? "未知"}
                                        </span>
        </div>
        <div className={"flex items-center w-full"}>
            <Label className={"flex-shrink-0 w-20"}>创建时间：</Label>
            <span
                className={"cursor-text overflow-hidden overflow-ellipsis  whitespace-nowrap break-words "}
                title={formatDate(new Date(it.createdAt), "yyyy-MM-dd HH:mm:ss")}>
                                            {formatDate(new Date(it.createdAt), "yyyy-MM-dd HH:mm:ss")}
                                        </span>
        </div>
    </Card>
}